<?php
require_once('lanceur_spip.php');
include_spip('functions/pdk_common');
//require_once(_DIR_PLUGIN_ALOHACART.'classes/ClientModel.php');
require_once(_DIR_PLUGIN_PDK.'classes/simpletest/class.PdkTest.php');

/**
 *  ExtensionModel class test case
 */
class TestClassAlohacart extends PdkTest {
    /**
     *  EcataloguE ProductModel
     */
    private $product_mdl;
    
    /**
     * EcataloguE CurrencyModel
     */
    private $currency_mdl;
    
    /**
     * Ecatalogue RubriqueCurrencyModel
     */
    private $rub_cur_mdl;
    
    /**
     * PdkRubriqueModel
     */
    private $rubrique_mdl;
    
    /**
     * PdkRubriqueModel
     */
    private $article_mdl;
    
    /**
     * CompositeArticleModel
     */
    private $composite_article_mdl;
    
    /**
     *  Alohacart
     */
    private $cart;
    
    private $session_variable;
    
    function __construct(){
        parent::__construct();
        // Define all additional models:
        $pdk_models = array();
        $this->product_mdl = pdk_load_class('ProductModel','classes');
        $pdk_models['ProductModel'] = $this->product_mdl;
        $this->currency_mdl = pdk_load_class('CurrencyModel','classes');
        $pdk_models['CurrencyModel'] = $this->currency_mdl;
        $this->rub_cur_mdl = pdk_load_class('RubriqueCurrencyModel','classes');
        $pdk_models['RubriqueCurrencyModel'] = $this->rub_cur_mdl;        
        $this->rubrique_mdl = pdk_load_class('PdkRubriqueModel','classes/models');
        $pdk_models['PdkRubriqueModel'] = $this->rubrique_mdl;
        $this->article_mdl = pdk_load_class('PdkArticleModel','classes/models');
        $pdk_models['PdkArticleModel'] = $this->article_mdl;
        $this->composite_article_mdl = pdk_load_class('CompositeArticleModel','classes');
        $pdk_models['CompositeArticleModel'] = $this->composite_article_mdl;                
        
        $this->AddPdkModels($pdk_models);
        
        $this->cart = pdk_load_class('Alohacart','classes');
        
        $this->dropTestTables = TESTS_DROP_TEST_TABLES;
        
        // Remember what is written in session, so later we can return it to initial state
        @session_start();
        $this->session_variable = &$_SESSION["alohacart"];
        $this->session_data = $this->session_variable;
        $this->session_variable_composite = &$_SESSION["alohacart_composite"];
        $this->session_data_composite = $this->session_variable_composite;
    }
        
    /**
     *  Run before each test
     */
    function setUp() {
        parent::setUp();
        
        // Clear cart before each test        
        $this->session_variable = array();
        $this->session_variable_composite = array();
    }
    
    /**
     *  Run after each test
     */
    function tearDown() {
        parent::tearDown();
    }
    
    function __destruct() {
        parent::__destruct();
        // Return session variable to initial state after testing                
        $this->session_variable = $this->session_data;
        $this->session_variable_composite = $this->session_data_composite;
    }
    
    function Test_AddProduct() {
        // Add one product        
        $this->cart->AddProduct(1, 5);        
        $this->assertEqual(5,$this->session_variable[1]);
        
        // Add product that alreary added into cart - quantity must be added
        $this->cart->AddProduct(1, 2);        
        $this->assertEqual(7,$this->session_variable[1]);
        
        // Add one more product - two products in the cart
        $this->cart->AddProduct(2, 3);        
        $this->assertEqual(2,count($this->session_variable));
    }
    
    function Test_RemoveProduct() {
        $this->session_variable[1] = 5;
        // Remove to pcs        
        $this->cart->RemoveProduct(1,2);  
        $this->assertEqual(3,$this->session_variable[1]);
        // Remove completely
        $this->cart->RemoveProduct(1);        
        $this->assertNull($this->session_variable[1]);
        
        $this->session_variable[1] = 5;
        // Remove quantity even more than actual in the cart
        $this->cart->RemoveProduct(1,10);
        $this->assertNull($this->session_variable[1]);
    }
    
    function Test_CountPrice() {
        // For this test we want all products to be in the same currency (with rate 1)
        $this->rub_cur_mdl->update(false, array("id_currency"=>2));
        $this->currency_mdl->update(false, array("rate"=>1));
        
        // If no products in cart - we must have 0
        $this->assertEqual(0,$this->cart->CountPrice());
        
        $this->session_variable[$this->product_mdl->test_data[0][$this->product_mdl->primary_key]] = 3;
        $this->session_variable[$this->product_mdl->test_data[1][$this->product_mdl->primary_key]] = 5;
        
        $price_check = $this->product_mdl->test_data[0]['price']*3 + $this->product_mdl->test_data[1]['price']*5;  
        $this->assertEqual($price_check, $this->cart->CountPrice());
    }
    
    function Test_CountProducts() {
        // If no products in cart - we must have 0
        $this->assertEqual(0,$this->cart->CountProducts());
        
        $this->session_variable[1] = 3;
        $this->session_variable[2] = 5;
        
        $this->assertEqual(8, $this->cart->CountProducts());
    }
    
    function Test_ClearCart() {
        $this->session_variable[1] = 3;
        $this->cart->ClearCart();
        $this->assertEqual(array(), $this->session_variable);
    }
    
    function Test_GetProductsIDs() {
        $this->session_variable[1] = 3;
        $this->session_variable[2] = 4;
        $this->session_variable[3] = 5;
        $this->assertEqual(array(1,2,3), $this->cart->GetProductsIDs());
    }
    
    function Test_UpdateProduct() {
        $this->session_variable[1] = 3;
        $this->cart->UpdateProduct(1, 5);
        $this->assertEqual(5, $this->session_variable[1]);
        
        // If qiven quantity is less than 0 - it must be 0
        $this->cart->UpdateProduct(1, -5);
        $this->assertEqual(0, $this->session_variable[1]);
    }
    
    function Test_GetProducts() {
        $this->session_variable[1] = 3;
        $this->session_variable[2] = 4;        
        $this->assertEqual(array('1'=>3,'2'=>4), $this->cart->GetProducts());
    }
    
    function Test_GetProductsTotals() {
        // For this test we want all products to be in the same currency (with rate 1)
        $this->rub_cur_mdl->update(false, array("id_currency"=>2));
        $this->currency_mdl->update(false, array("rate"=>1));
        
        $this->session_variable[1] = 3;
        $this->session_variable[2] = 4;        
        $this->assertEqual(array('1'=>3*$this->product_mdl->test_data[0]['price'],'2'=>4*$this->product_mdl->test_data[1]['price']), 
            $this->cart->GetProductsTotals());
    }
    
    function Test_UpdateCompositeProduct() {
        $this->cart->UpdateCompositeProduct(10,20,30);
        $this->cart->UpdateCompositeProduct(10,30,20);
        $this->assertEqual(array(10=>array(20=>30,30=>20)), $this->session_variable_composite);
        
        $this->session_variable_composite = array();
        // If qiven quantity is less than 1 - it must be 1
        $this->cart->UpdateCompositeProduct(2,4,-4);
        $this->assertEqual(array(2=>array(4=>1)), $this->session_variable_composite);
        
        $this->session_variable_composite = array();
        // If given quantity is more than set for component of composite product, it must be set to this quantity
        $this->cart->UpdateCompositeProduct(1,3,3);
        $this->assertEqual(array(1=>array(3=>2)), $this->session_variable_composite);
        
        // When quantity of composite product in the cart is more than 1, that must be taken to consideration
        // when updating composite
        $this->cart->AddProduct(1);
        $this->cart->UpdateCompositeProduct(1,3,3);
        $this->assertEqual(array(1=>array(3=>3)), $this->session_variable_composite);
    }
    
    function Test_GetCompositeProduct() {
        $this->session_variable_composite = array(1=>array(2=>3,3=>2));
        $this->assertEqual(2, $this->cart->GetCompositeProduct(1, 3));
                
        $this->assertEqual(false, $this->cart->GetCompositeProduct(10, 3));        
    }
    
    function Test_CompositeQuantityMustBeUnsetWhenProductAdded() {
        $this->cart->UpdateCompositeProduct(1,3,1);
        $this->cart->AddProduct(1);        
        $this->assertEqual(false, $this->cart->GetCompositeProduct(1, 3));
    }
}